#pragma once

#include "iostream"
#include "vector"
#include "algorithm"

using namespace std;
/*HJJ QQ479287006
 峰值元素是指其值严格大于左右相邻值的元素。

给你一个整数数组 nums，找到峰值元素并返回其索引。数组可能包含多个峰值，在这种情况下，返回 任何一个峰值 所在位置即可。

你可以假设 nums[-1] = nums[n] = -∞ 。

你必须实现时间复杂度为 O(log n) 的算法来解决此问题。

 

示例 1：

输入：nums = [1,2,3,1]
输出：2
解释：3 是峰值元素，你的函数应该返回其索引 2。
示例 2：

输入：nums = [1,2,1,3,5,6,4]
输出：1 或 5
解释：你的函数可以返回索引 1，其峰值元素为 2；
     或者返回索引 5， 其峰值元素为 6。

来源：力扣（LeetCode）
链接：https://leetcode.cn/problems/find-peak-element
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。*
 * */

//四种情况
//就是逼近
int findPeakElement(vector<int> &nums) {
    if (nums.size() <= 1)
        return 0;

    int low = 0;
    int high = nums.size() - 1;

    //这边边界也有问题必须 low<=high
    while (low <= high) {
        int mid = low + (high - low) / 2;

        //可能越界
        //这边有一点疑惑 你去顶mid==0 或者那个等于最大值的时候一定是这个极值点吗 因为一直在筛选出来了
        if (((mid == nums.size() - 1) || nums[mid] > nums[mid + 1]) && (mid == 0 || nums[mid] > nums[mid - 1]))
            return mid;


        //这边左右逼近任意一个最值
        if (nums[mid] > nums[mid + 1]) {
            high = mid - 1;
        } else {

            low = mid + 1;
        }


    }
    return -1;
}


/*这样写比较合理
 *     int findPeakElement(vector<int>& nums) {
           if (nums.size() <= 1)
        return 0;
        int low=0;
        int high=nums.size()-1;

        while(low<=high)
        {
            int mid=low+(high-low)/2;

            // 什么时候返回?
            if(((mid==nums.size()-1)||nums[mid]>nums[mid+1])&&(mid==0||nums[mid]>nums[mid-1]))
            return mid;


          if (nums[mid] > nums[mid + 1]) {
            high = mid;
        } else {

            low = mid + 1;
        }
        }
        return -1;
    }
 *
 * */